package jxtcp

import (
	"bufio"
	"encoding/binary"
	"io"

	"github.com/google/uuid"
	"github.com/vmihailenco/msgpack/v5"
)

type Message struct {
	Id        string
	Type      uint32
	MachineId uint32
	Data      []byte
	MoreInfo  string
}
type Progress struct {
	Max   float64
	Value float64
	Add   float64
}
type MessageOption func(*Message)

var UUIDLength = uint32(36)

func MachineId(mid uint32) MessageOption {
	return func(m *Message) {
		m.MachineId = mid
	}
}

// WithType 选项
func Type(msgType uint32) MessageOption {
	return func(m *Message) {
		m.Type = msgType
	}
}
func MoreInfo(msg string) MessageOption {
	return func(m *Message) {
		m.MoreInfo = msg
	}
}
func NewMessage(data []byte, opts ...MessageOption) *Message {
	outData := &Message{
		Id:   uuid.NewString(),
		Data: data,
	}
	for _, val := range opts {
		val(outData)
	}
	return outData
}

// 从连接读取消息
func ReadMessage(r *bufio.Reader) (*Message, error) {
	// 1. 读取长度前缀
	var length uint32
	if err := binary.Read(r, binary.BigEndian, &length); err != nil {
		return nil, err
	}

	// 2. 读取消息体
	body := make([]byte, length)
	if _, err := io.ReadFull(r, body); err != nil {
		return nil, err
	}

	// 3. 反序列化
	var msg Message
	err := msgpack.Unmarshal(body, &msg)
	return &msg, err
}

// 将消息写入连接
func (m *Message) WriteMessage(w *bufio.Writer) error {
	// 1. 序列化消息体
	body, err := msgpack.Marshal(m)
	if err != nil {
		return err
	}

	// 2. 构建带长度前缀的数据包
	buf := make([]byte, 4+len(body))
	binary.BigEndian.PutUint32(buf[:4], uint32(len(body)))
	copy(buf[4:], body)

	// 3. 执行写入
	_, err = w.Write(buf)
	if err != nil {
		return err
	}
	return w.Flush()
}
